(function() {

	// test for bugging trim (from https://gist.github.com/a430ee32c65f10e7500c)
	var whitespaceChars = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002'+
												'\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029';
	if (!String.prototype.trim || whitespaceChars.trim().length > 0) {
		String.prototype.trim = function trim() {
			return this.replace(/^\s*/, '').replace(/\s*$/, '');
		};
		String.prototype.ltrim = function ltrim() {
			return this.replace(/^\s*/, '');
		};
		String.prototype.rtrim = function rtrim() {
			return this.replace(/\s*$/, '');
		};
	}
	String.prototype.strip = String.prototype.trim;

	String.prototype.include = function include(pattern) {
		return this.indexOf(pattern) > -1;
	};

	String.prototype.startsWith = function startsWith(pattern) {
		return this.indexOf(pattern) === 0;
	};
	// from Prototype 1.6.1
	String.prototype.endsWith = function endsWith(pattern) {
		var d = this.length - pattern.length;
		return d >= 0 && this.lastIndexOf(pattern) === d;
	};

	String.interpret = function interpret(o) {
		return typeof o === 'undefined' ? '' : o + '';
	};

	/**
	 * Replace all the instances of one string with another (Similar to Prototype's String#gsub)
	 *   WARNING: Passing a RegExp with the 'g' flag will cause an infinite loop
	 *
	 * @param {String} string  The haystack
	 * @param {String|RegExp} pattern  The needle
	 * @param {String|Function} replacement  The replacement string or function that receives the match array and returns a new string
	 * @param {Number} [limit=0] If this number of matches is met, abort
	 * @return {String}
	 */
	String.prototype.replaceAll = function replaceAll(pattern, replacement, limit) {
		// string must be copied to "source" to allow methodizing
		var result = '', source = this, match, count = 0;
		// ensure replacement is a function
		if (typeof replacement != 'function') {
			var strRepl = castAsString(replacement);
			/** @ignore */
			replacement = function() { return strRepl; };
		}
		limit = limit >>> 0;

		while (source.length > 0 && (match = source.match(pattern))) {
			// we found a match, so reset source up to this point
			result += source.slice(0, match.index);
			// add the replacement instead of the match
			result += castAsString(replacement(match, count++));
			source = source.slice(match.index + match[0].length);
			if (limit > 0 && limit <= count) {
				break;
			}
		}
		result += source;
		return result;
	}
	String.prototype.gsub = String.prototype.replaceAll;

	// from Prototype 1.6.1
	String.prototype.truncate = function truncate(length, truncation) {
		length = length || 30;
		truncation = typeof truncation == 'undefined' ? '...' : truncation;
		return this.length > length ?
			this.slice(0, length - truncation.length) + truncation : String(this);
	};
	// from Prototype 1.6.1
	String.prototype.stripTags = function stripTags() {
		return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
	};

		/**
		 * Replace placeholder tags with values
		 *
		 * @param {String} text  The template text
		 * @param {Object} hash  Object containing name-value pairs of tags-values that need to be replaced
		 * @param {RegExp} [tagMatcher=/(^|[^\\])\{\$([\w]+)}/]  RegExp designed to find tags (default is "{$tag}" format tags)
		 * @return {String}
		 * @example pulp.base.tpl('My favorite food is {$food}.', {food: 'pizza'}) // "My favorite food is pizza."
		 */
	String.prototype.interpolate = function interpolate(pairs, tagMatcher) {
		return this.replaceAll(tagMatcher || String.prototype.interpolate.pattern, function(match) {
			var v = pairs[match[2]];
			return match[1] + (typeof v == 'undefined' ? '' : v + '');
		});
	};
	String.prototype.interpolate.pattern = /(^|[^\\])\{\$([\w]+)}/;
	// from Prototype 1.6.1
	String.prototype.capitalize = function capitalize() {
		return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
	};

	var trim = null,
		ltrim = null,
		rtrim = null,
		include = null,
		startsWith = null,
		endsWith = null,
		empty = null,
		interpret = null,
		replaceAll = null,
		truncate = null,
		stripTags = null,
		interpolate = null,
		capitalize = null;

})();
